package com.yeban.bams.dao;

import com.yeban.bams.entity.Account;
import com.yeban.bams.mapper.*;
import com.yeban.bams.vo.BaseAccountDTO;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Desc TODO
 * @Author yeban
 * @Date 2025/11/21
 */
public class JDBCDao implements IDao<Account, List<Account>> {

    private static SqlSessionFactory factory;

    // 初始ID
    private Long ORIGINAL_ID = 100000000000000000L; //初始 ID
    private Long currentId;     // 当前ID

    public JDBCDao() {
        try {
            if (factory == null) {
                InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
                factory = new SqlSessionFactoryBuilder().build(is);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // 每次数据库操作开启一个 Session（自动提交）
    private SqlSession openSession() {
        return factory.openSession(true);
    }

    /**
     * 添加账户信息
     * @param acc
     * @return
     */
    @Override
    public boolean insert(Account acc) {
        try (SqlSession session = openSession()) {
            switch (acc.getType()) {
                case 0:
                    return session.getMapper(SavingAccountMapper.class).insert(acc);
                case 1:
                    return session.getMapper(CreditAccountMapper.class).insert(acc);
                case 2:
                    return session.getMapper(LoanableSavingsAccountMapper.class).insert(acc);
                case 3:
                    return session.getMapper(LoanableCreditAccountMapper.class).insert(acc);
                default:
                    System.out.println("账户类型不存在！");
                    return false;
            }
        }
    }

    /**
     * 根据id和密码查询
     * @param id
     * @param pwd
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    @Override
    public Account selectOne(Long id, String pwd) {
        try (SqlSession session = openSession()) {
            // 1. 查询基础信息以获取 type
            BaseAccountMapper baseMapper = session.getMapper(BaseAccountMapper.class);
            BaseAccountDTO base = baseMapper.selectBaseByIdAndPwd(id, pwd);
            if (base == null) return null;

            // 2. 根据类型分发 Mapper
            switch (base.getType()) {
                case 0:
                    return session.getMapper(SavingAccountMapper.class).selectByAccountId(id);
                case 1:
                    return session.getMapper(CreditAccountMapper.class).selectByAccountId(id);
                case 2:
                    return session.getMapper(LoanableSavingsAccountMapper.class).selectByAccountId(id);
                case 3:
                    return session.getMapper(LoanableCreditAccountMapper.class).selectByAccountId(id);
                default:
                    return null;
            }
        }
    }

    /**
     * 根据id查询账户
     * @param id
     * @return
     */
    @Override
    public Account selectOne(Long id) {
        try (SqlSession session = openSession()) {
            BaseAccountMapper baseMapper = session.getMapper(BaseAccountMapper.class);
            BaseAccountDTO  base = baseMapper.selectBaseById(id);
            if (base == null) return null;

            switch (base.getType()) {
                case 0:
                    return session.getMapper(SavingAccountMapper.class).selectByAccountId(id);
                case 1:
                    return session.getMapper(CreditAccountMapper.class).selectByAccountId(id);
                case 2:
                    return session.getMapper(LoanableSavingsAccountMapper.class).selectByAccountId(id);
                case 3:
                    return session.getMapper(LoanableCreditAccountMapper.class).selectByAccountId(id);
                default:
                    return null;
            }
        }
    }

    /**
     * 查询所有账户
     * @return
     */
    @Override
    public List<Account> selectAll() {
        try (SqlSession session = openSession()) {
            BaseAccountMapper baseMapper = session.getMapper(BaseAccountMapper.class);
            List<BaseAccountDTO > baseList = baseMapper.selectAllBase();
            List<Account> result = new ArrayList<>();

            for (BaseAccountDTO base : baseList) {
                Long id = base.getId();
                int type = base.getType();
                switch (type) {
                    case 0:
                        result.add(session.getMapper(SavingAccountMapper.class).selectByAccountId(id));
                        break;
                    case 1:
                        result.add(session.getMapper(CreditAccountMapper.class).selectByAccountId(id));
                        break;
                    case 2:
                        result.add(session.getMapper(LoanableSavingsAccountMapper.class).selectByAccountId(id));
                        break;
                    case 3:
                        result.add(session.getMapper(LoanableCreditAccountMapper.class).selectByAccountId(id));
                        break;
                }
            }
            return result;
        }
    }

    // 更新账户信息
    @Override
    public void update(Account acc) {
        try (SqlSession session = openSession()) {
            switch (acc.getType()) {
                case 0:
                    session.getMapper(SavingAccountMapper.class).update(acc);
                    break;
                case 1:
                    session.getMapper(CreditAccountMapper.class).update(acc);
                    break;
                case 2:
                    session.getMapper(LoanableSavingsAccountMapper.class).update(acc);
                    break;
                case 3:
                    session.getMapper(LoanableCreditAccountMapper.class).update(acc);
                    break;
            }
        }
    }

    // 获取账户id
    @Override
    public Long getId() {
        try (SqlSession session = openSession()) {
            NextIdMapper nextIdMapper = session.getMapper(NextIdMapper.class);
            Long nextId = nextIdMapper.selectNextId();
            // 如果 nextid 表为空，初始化一个默认值
            if (nextId == null) {
                nextId = ORIGINAL_ID;
                nextIdMapper.insertNextId(nextId);
            }
            return nextId;
        }
    }

    // 设置账户id
    @Override
    public void setId(Long id) {
        try (SqlSession session = openSession()) {
            NextIdMapper nextIdMapper = session.getMapper(NextIdMapper.class);
            // 检查表中是否有记录
            Long existingId = nextIdMapper.selectNextId();
            if (existingId == null) {
                // 如果表为空，插入新记录
                nextIdMapper.insertNextId(id);
            } else {
                // 如果表有记录，更新记录
                nextIdMapper.updateNextId(id);
            }
        }
    }

}